package org.future.dataanalysis;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.future.dataanalysis.bean.*;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author Dongwei-Chen
 * @Date 2023/12/19 11:11
 * @Description
 */
public class ObjectAnalysis extends AnalysisServer {

    private String topic;

    private String uniqueId;

    private String[] pkFields;

    private String groupField;

    private State state;

    private BaseObjectAnalysis baseObjectAnalysis;

    private Node itemNode;

    public ObjectAnalysis(String uniqueId, Map<String, String> entity, State state) {
        try {
            String analysisClass = entity.get("analysisClass");
            baseObjectAnalysis = (BaseObjectAnalysis) Class.forName(analysisClass).newInstance();
            topic = entity.get("topic");
            String pkField = entity.get("pkField");
            if (pkField != null) {
                pkFields = pkField.split("\\,");
            }
            groupField = entity.get("groupField");
            this.uniqueId = uniqueId;
            String analysis = entity.get("analysis");

            //此处可以根据不同数据项获取对应解析节点数据
            Node node;
            if (analysis != null) {
                JSONObject jsonObject = JSON.parseObject(analysis);
                node = createNode(jsonObject);
                this.itemNode = node;
            }
            this.state = state;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private Node createNode(JSON json) {
        Node node = null;
        if (json instanceof JSONObject) {
            node = new Node(Type.OBJECT);
            JSONObject jsonObject = (JSONObject) json;
            for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
                String key = entry.getKey();
                Object value = entry.getValue();
                if (value instanceof String) {
                    //没有子节点
                    node.putDataField(key, (String) value);
                    continue;
                }
                Node resultNode = createNode((JSON) value);
                node.putNodeMap(entry.getKey(), resultNode);
            }
        } else if (json instanceof JSONArray) {
            JSONArray jsonArray = (JSONArray) json;
            node = new Node(Type.ARRAY);
            node.setFlat(true);
            Node childNode = createNode((JSON) jsonArray.get(0));
            node.setDataMap(childNode.getDataMap());
        }

        return node;
    }

    @Override
    RecursionResult analysis(JSONObject json, DataUnit dataUnit) {
        //先解析公共数据
        RecursionResult recursionResult = new RecursionResult();
        if (itemNode != null) {
            RecursionResult dataResult = getData(json, itemNode, recursionResult, null);
            List<DataUnit> finalMaps = dataResult.getFinalMaps();
            if (CollectionUtil.isNotEmpty(finalMaps)) {
                for (DataUnit finalMap : finalMaps) {
                    Map<String, Object> dataArea = finalMap.getDataArea();
                    dataArea.putAll(dataUnit.getDataArea());
                    full(finalMap, json, recursionResult);
                }
                return recursionResult;
            }
        } else {
            return full(dataUnit, json, recursionResult);
        }
        return null;
    }

    private RecursionResult full(DataUnit unit, JSONObject json, RecursionResult recursionResult) {
        unit.setTopic(topic);
        unit.setDataItemId(uniqueId);
        List<DataUnit> analysis = baseObjectAnalysis.analysis(uniqueId, unit, json, state);
        if (analysis != null) {
            //获取主键和分组
            List<DataUnit> collect = analysis.stream().map(fullData -> {
                Map<String, Object> dataArea = fullData.getDataArea();
                Object group = dataArea.get(groupField);
                if (group == null) {
                    return null;
                }
                if (pkFields != null) {
                    StringBuilder pkFieldsConcat = new StringBuilder();
                    for (String field : pkFields) {
                        Object pkField = dataArea.get(field);
                        if (pkField == null) {
                            return null;
                        }
                        pkFieldsConcat.append(pkField).append("#");
                    }
                    pkFieldsConcat.deleteCharAt(pkFieldsConcat.length() - 1);
                    fullData.setPkFields(pkFieldsConcat.toString());
                }
                fullData.setGroupId(String.valueOf(group));
                return fullData;
            }).filter(Objects::nonNull).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(collect)) {
                recursionResult.getAllDataUnit().addAll(collect);
            }
        }
        return recursionResult;
    }

    @Override
    public boolean associatedArchives(DataUnit dataUnit, Map<String, String> redisMap) {
        try {
            return baseObjectAnalysis.association(dataUnit, redisMap);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
}
